home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / cloud9.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  9KB  |  314 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12.  
  13. unsigned char *cloud9_vram2;
  14. unsigned char *cloud9_bitmap_regs;
  15. unsigned char *cloud9_auto_inc_x;
  16. unsigned char *cloud9_auto_inc_y;
  17. unsigned char *cloud9_both_banks;
  18. unsigned char *cloud9_vram_bank;
  19. unsigned char *cloud9_color_bank;
  20.  
  21.  
  22. /***************************************************************************
  23.   cloud9_paletteram_w
  24.  
  25.   Cloud 9 uses 9-bit color, in the form RRRGGGBB, with the LSB of B stored
  26.   in the $40 bit of the address.
  27. ***************************************************************************/
  28. WRITE_HANDLER( cloud9_paletteram_w )
  29. {
  30.     int bit0,bit1,bit2;
  31.     int r,g,b;
  32.     int blue;
  33.  
  34.  
  35.     paletteram[(offset & 0x3f)] = data;
  36.     blue = (offset & 0x40);
  37.  
  38.     /* red component */
  39.     bit0 = (~data >> 5) & 0x01;
  40.     bit1 = (~data >> 6) & 0x01;
  41.     bit2 = (~data >> 7) & 0x01;
  42.     r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  43.  
  44.     /* green component */
  45.     bit0 = (~data >> 2) & 0x01;
  46.     bit1 = (~data >> 3) & 0x01;
  47.     bit2 = (~data >> 4) & 0x01;
  48.     g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  49.  
  50.     /* blue component */
  51.     bit0 = (~blue >> 6) & 0x01;
  52.     bit1 = (~data >> 0) & 0x01;
  53.     bit2 = (~data >> 1) & 0x01;
  54.     b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  55.  
  56.     palette_change_color((offset & 0x3f),r,g,b);
  57. }
  58.  
  59. /***************************************************************************
  60.  The video system is a little bit odd.
  61.  
  62.  It consists of a 256x240 bitmap, that can apparently be indexed both
  63.  directly and indirectly.
  64.  
  65.  Indirect Indexing:
  66.  This is accomplished through memory locations 0x0000, 0x0001, 0x00002.
  67.  0 = The x index on the bitmap
  68.  1 = The y index on the bitmap
  69.  2 = The pixel value for that (x,y) location (this will be 0x00-0x0F).
  70.  
  71.  Direct Indexing:
  72.  Somehow, the bitmap is mapped to locations 0x600-0x3FFF.  Since a 256x256
  73.  bitmap would theoretically need 0x10000 bytes, we need a way to compress
  74.  it.  We can reduce it to 0x8000 bytes by storing two pixels to a byte.
  75.  To drop it down to 0x4000 bytes, we're going to assume there is two banks
  76.  of video memory.  Since Cloud9 doesn't provide many examples for how these
  77.  bytes are accessed, the following are guesses that seem to work.  If other
  78.  games use this hardware, feel free to try modifying the following
  79.  assumptions.  We'll assume that:
  80.  X & 0x03 == 0 - store at bank0, lo nibble
  81.  X & 0x03 == 1 - store at bank0, hi nibble
  82.  X & 0x03 == 2 - store at bank1, lo nibble
  83.  X & 0x03 == 3 - store at bank1, hi nibble
  84.  For Cloud9 to work, it's only important that writing 0's to 0x0600-0x3FFF
  85.  clears the bitmap.  Oddly enough, to clear the bitmap, it only writes to
  86.  0x0600-0x3FFF once, which leads me to believe there's a register that allows
  87.  both banks to be written to at once, and a register to allow a specific bank
  88.  to be selected.
  89.  
  90. ***************************************************************************/
  91.  
  92.  
  93. /***************************************************************************
  94.   ConvertPoint
  95.  
  96.   This is used to take an x,y location and convert it to the proper memory
  97.   address, bank, and nibble.  This is pure speculation.
  98. ***************************************************************************/
  99. static void convert_point(unsigned int x, unsigned int y, unsigned char **vptr, int *vpixel)
  100. {
  101.     unsigned int voff;
  102.  
  103.     voff = (y << 6) + (x >> 2) - 0x600;
  104.  
  105.     switch (x & 0x02)
  106.     {
  107.     case 0x00:
  108.         *vptr = &(videoram[voff]);
  109.         break;
  110.     case 0x02:
  111.         *vptr = &(cloud9_vram2[voff]);
  112.         break;
  113.     }
  114.  
  115.     switch (x & 0x01)
  116.     {
  117.     case 0x00:
  118.         *vpixel = (**vptr & 0x0f) >> 0;
  119.         break;
  120.     case 0x01:
  121.         *vpixel = (**vptr & 0xf0) >> 4;
  122.         break;
  123.     }
  124. }
  125.  
  126. /***************************************************************************
  127.   cloud9_bitmap_regs_r
  128. ***************************************************************************/
  129. READ_HANDLER( cloud9_bitmap_regs_r )
  130. {
  131.     unsigned char *vptr;
  132.     int vpixel;
  133.     unsigned int x, y;
  134.  
  135.     x = cloud9_bitmap_regs[0];
  136.     y = cloud9_bitmap_regs[1];
  137.  
  138.     switch (offset)
  139.     {
  140.     case 0:
  141.         /* Indirect Addressing - X register */
  142.         return x;
  143.     case 1:
  144.         /* Indirect Addressing - Y register */
  145.         return y;
  146.     case 2:
  147.         /* Indirect Addressing - pixel value at (X,Y) */
  148.         if (y < 0x0c)
  149.         {
  150.             logerror("Unexpected read from top of bitmap!\n");
  151.             return 0;
  152.         }
  153.  
  154.         convert_point(x,y,&vptr,&vpixel);
  155.         return vpixel;
  156.     }
  157.  
  158.     return 0;
  159. }
  160.  
  161. /***************************************************************************
  162.   cloud9_bitmap_regs_w
  163. ***************************************************************************/
  164. WRITE_HANDLER( cloud9_bitmap_regs_w )
  165. {
  166.     unsigned int x, y;
  167.  
  168.     cloud9_bitmap_regs[offset] = data;
  169.  
  170.     x = cloud9_bitmap_regs[0];
  171.     y = cloud9_bitmap_regs[1];
  172.  
  173.     if (offset == 2)
  174.     {
  175.         /* Not quite sure how these writes map to VRAM
  176.            (Cloud9 only directly writes 00 to VRAM and doesn't read it) */
  177.  
  178.         /* Don't allow writes to memory at less than 0x600 */
  179.         if (y >= 0x0c)
  180.         {
  181.             unsigned char *vptr;
  182.             int vpixel;
  183.  
  184.             convert_point(x,y,&vptr,&vpixel);
  185.  
  186.             /* This is a guess */
  187.             switch (x & 0x01)
  188.             {
  189.             case 0x00:
  190.                 *vptr = (*vptr & 0xf0) | ((data & 0x0f) << 0);
  191.                 break;
  192.             case 0x01:
  193.                 *vptr = (*vptr & 0x0f) | ((data & 0x0f) << 4);
  194.                 break;
  195.             }
  196.  
  197.         }
  198.  
  199.         /* If color_bank is set, add 0x20 to the color */
  200.         plot_pixel(tmpbitmap, x, y, Machine->pens[(data & 0x0f) + ((*cloud9_color_bank & 0x80) >> 2)]);
  201.  
  202.         if ((*cloud9_auto_inc_x) < 0x80)
  203.             cloud9_bitmap_regs[0]++;
  204.  
  205.         if ((*cloud9_auto_inc_y) < 0x80)
  206.             cloud9_bitmap_regs[1]++;
  207.     }
  208. }
  209.  
  210. /***************************************************************************
  211.   cloud9_bitmap_w
  212. ***************************************************************************/
  213. WRITE_HANDLER( cloud9_bitmap_w )
  214. {
  215.     UINT8 x, y;
  216.  
  217.     y = ((offset + 0x600) >> 6);
  218.     x = ((offset + 0x600) & 0x3f) << 2;
  219.  
  220.     if (*cloud9_both_banks & 0x80)
  221.     {
  222.         videoram[offset] = data;
  223.         cloud9_vram2[offset] = data;
  224.  
  225.         plot_pixel(tmpbitmap, x,   y, Machine->pens[((data & 0x0f) >> 0) + ((*cloud9_color_bank & 0x80) >> 2)]);
  226.         plot_pixel(tmpbitmap, x+1, y, Machine->pens[((data & 0xf0) >> 4) + ((*cloud9_color_bank & 0x80) >> 2)]);
  227.         plot_pixel(tmpbitmap, x+2, y, Machine->pens[((data & 0x0f) >> 0) + ((*cloud9_color_bank & 0x80) >> 2)]);
  228.         plot_pixel(tmpbitmap, x+3, y, Machine->pens[((data & 0xf0) >> 4) + ((*cloud9_color_bank & 0x80) >> 2)]);
  229.     }
  230.     else if (*cloud9_vram_bank & 0x80)
  231.     {
  232.         cloud9_vram2[offset] = data;
  233.  
  234.         plot_pixel(tmpbitmap, x+2, y, Machine->pens[((data & 0x0f) >> 0) + ((*cloud9_color_bank & 0x80) >> 2)]);
  235.         plot_pixel(tmpbitmap, x+3, y, Machine->pens[((data & 0xf0) >> 4) + ((*cloud9_color_bank & 0x80) >> 2)]);
  236.     }
  237.     else
  238.     {
  239.         videoram[offset] = data;
  240.  
  241.         plot_pixel(tmpbitmap, x  , y, Machine->pens[((data & 0x0f) >> 0) + ((*cloud9_color_bank & 0x80) >> 2)]);
  242.         plot_pixel(tmpbitmap, x+1, y, Machine->pens[((data & 0xf0) >> 4) + ((*cloud9_color_bank & 0x80) >> 2)]);
  243.     }
  244. }
  245.  
  246. /***************************************************************************
  247.  
  248.   Draw the game screen in the given osd_bitmap.
  249.   Do NOT call osd_update_display() from this function, it will be called by
  250.   the main emulation engine.
  251.  
  252. ***************************************************************************/
  253. static void redraw_bitmap(void)
  254. {
  255.     int offs;
  256.  
  257.     int cloud9_both_banks_save = *cloud9_both_banks;
  258.     int cloud9_vram_bank_save  = *cloud9_vram_bank;
  259.  
  260.     *cloud9_both_banks = 0;
  261.  
  262.     for (offs = 0; offs < videoram_size; offs++)
  263.     {
  264.         *cloud9_vram_bank = 0;
  265.         cloud9_bitmap_w(offs, videoram[offs]);
  266.  
  267.         *cloud9_vram_bank = 0x80;
  268.         cloud9_bitmap_w(offs, cloud9_vram2[offs]);
  269.     }
  270.  
  271.     *cloud9_both_banks = cloud9_both_banks_save;
  272.     *cloud9_vram_bank  = cloud9_vram_bank_save;
  273. }
  274.  
  275.  
  276. void cloud9_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  277. {
  278.     int offs;
  279.  
  280.  
  281.     if (palette_recalc())
  282.     {
  283.         redraw_bitmap();
  284.     }
  285.  
  286.  
  287.     copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  288.  
  289.  
  290.     /* draw the sprites */
  291.     for (offs = 0;offs < 20;offs++)
  292.     {
  293.         int spritenum;
  294.         int xflip,yflip,rblank,lblank;
  295.         int x, y;
  296.  
  297.         spritenum = spriteram[offs + 0x20];
  298.  
  299.         xflip  = (spriteram[offs + 0x40] & 0x80);
  300.         yflip  = (spriteram[offs + 0x40] & 0x40);
  301.         rblank = (spriteram[offs + 0x40] & 0x20);
  302.         lblank = (spriteram[offs + 0x40] & 0x10);
  303.         x = spriteram[offs + 0x60];
  304.         y = 240 - spriteram[offs];
  305.  
  306.         drawgfx(bitmap,Machine->gfx[2],
  307.                 spritenum,
  308.                 1 + ((*cloud9_color_bank & 0x80) >> 6),
  309.                 xflip,yflip,
  310.                 x,y,
  311.                 &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  312.     }
  313. }
  314.